﻿using System;
using System.Collections.Generic;
using Battle.Engine.InputData;
using Dict.DataModel;
using Dict.Dao;
using Dict;
using Dict.Config;

namespace Battle.Engine.LogicModel
{
    //状态
    public enum FActorState
    {
        IDLE = 0,       //在原始位置待命
        SKILL = 1,      //释放技能
        WAIT = 2,       //攻击完在原地待命,不回去
        WAEKDEAD = 3,   //假死状态
        DEAD = 4,       //真死
    }

    public class FActor
    {
        public FPlayer player;                  //Actor所属于的玩家
        public FActorState state;               //玩家的状态
        public bool isReboundBuff;          //复活buff是否被启用过
        public bool isRebound;              //是否被复活过
        public bool isRelive;               //死亡后是否重生过

        public string uniqueId;                //guid
        public string heroId;                   //
        public int breachedLevel;            //人物突破等级
        public TableHero heroData;              //mxd 是否需要保存
        public int heroClass;                   //
        public FPosition MainPosition;          //人的具体位置
        public FPosition position;              //人中心所在的位置
        public List<FPosition> positions;       //人所占的位置
        public List<FSkill> skills;             //人身上的技能
        public List<FTalent> talents;           //人身上的天赋

        public int space;                   //世界
        public SpeState defaultSpeState;        //默认的状态
        public List<SpeState> unableStates;     //不可达到的特殊状态   
        public SpeState speState;               //站立倒地浮空状态
        public double floatStartTime;          //浮空开始计时的时间
        public double floatTime;               //浮空的时间
        public double fallStartTime;           //倒地开始计时的时间
        public double fallTime;                //倒地的时间
        public int selfComboNum;

        public FAttribute attribute;            //人身上的属性
        public FStateManager stateManager;      //人身上的状态管理
        public FBuffManager buffManager;        //人身上的buff管理
        public FBuffProc buffProc;          //天赋处理
        public AttackType attackType; //第一个小招的攻击类型（若第一招为治疗则取第二招）
        public SkillClass curSkillClass; //当前正在释放的技能类型

        public FSkill doSkill = null;          //正在释放的普通技能
        public List<FSkill> waitSkills;         //正在等待执行的普通技能
        public FSkill doUltimateSkill = null;   //正在释放的大招
        public double ultimateCostAnger = 0;    //大招释放需要的怒气值
        public List<FActor> behitActors;        //记录已被当前技能命中过的人

        public FPosition curCastTargetPosition; //内部数据,攻击时选取目标的位置
        public int curCastSelectPointRule;      //内部数据,攻击站位的选取规则
        public double waitTime = 0;             //攻击完等待的时间

        public double firstSkillCastChance = 0; //第一个技能释放概率，只有Actor为怪物且有两个普通技能可以释放的时候会使用

        public int aiProperty;                  //AI优先级

        public double exportTreatHp = 0;
        public double exportDamHp = 0;

        public void init(FPlayer player, InActorData actorData, EngineData data)
        {
            this.player = player;

            this.isReboundBuff = false;
            this.isRebound = false;
            this.isRelive = false;
            this.uniqueId = actorData.uniqueId;
            this.heroId = actorData.heroId;
            this.breachedLevel = actorData.breachedLevel;
            this.attribute = new FAttribute(this, actorData);
            this.stateManager = new FStateManager(this);
            this.buffManager = new FBuffManager(this);
            this.buffProc = new FBuffProc(this);

            this.heroData = DictDataManager.Instance.tableHeroDao.GetById(this.heroId);

            this.aiProperty = heroData.aiProperty;

            this.space = this.heroData.space;
            this.defaultSpeState = (SpeState)this.heroData.DefaultState; //默认的SPE状态
            this.unableStates = new List<SpeState>();//不可到达的SPE状态
            string[] imposStates = heroData.ImposState.Split(',');
            foreach (var str in imposStates)
            {
                this.unableStates.Add((SpeState)int.Parse(str));
            }
            this.speState = (SpeState)this.heroData.DefaultState;//当前的SPE状态
            this.floatStartTime = data.roundTime;
            this.floatTime = 0;
            this.fallStartTime = data.roundTime;
            this.fallTime = 0;
            this.selfComboNum = 0;
            //站位
            this.positions = new List<FPosition>();
            this.positions.Add(new FPosition(actorData.fpid, player.camp));
            ResetPosition();
            this.MainPosition = positions[0];

            //初始化技能
            skills = new List<FSkill>();
            heroClass = heroData.heroClass;
            this.attackType = AttackType.NONE;
            this.curSkillClass = SkillClass.None;
            foreach (var obj in actorData.skills)
            {
                FSkill skill = new FSkill();
                skill.init(this, obj.id, obj.index, data);
                skills.Add(skill);
                if(this.attackType == AttackType.NONE && obj.index == 0 && skill.attackType != AttackType.TREAT)
                {
                    this.attackType = skill.attackType;
                }
                else if(this.attackType == AttackType.NONE && obj.index == 1 && skill.attackType != AttackType.TREAT)
                {
                    this.attackType = skill.attackType;
                }
            }
            if (this.attackType == AttackType.NONE)
            {
                Debug.LogError("There is no normal attack skill type of hero:" + this.heroId);
                this.attackType = AttackType.PHY;
            }
            this.behitActors = new List<FActor>();
            //初始化天赋
            talents = new List<FTalent>();
            foreach (var obj in actorData.talents)
            {
                if (data.tableDataUtil.GetTableTalent(obj.id) != null)
                {
                    FTalent talent = new FTalent();
                    talent.init(this, obj.id, data);
                    talents.Add(talent);
                }
            }

            //{
            //    //添加测试天赋1
            //    var talent = new FTalent();
            //    talent.init(this, "test_tal_rebound", data);
            //    talents.Add(talent);
            //}

            this.ultimateCostAnger = this.player.engineData.tableDataUtil.GetUltimateCostAnger();
            doSkill = null;
            waitSkills = new List<FSkill>();

            this.firstSkillCastChance = actorData.firstSkillChance;

            //初始血量小于0，直接判定死亡
            if (this.attribute.hp <= 0)
            {
                this.state = FActorState.DEAD;
            }
        }
        
        public void AddHp(double addhp, FExportOnceData exportOnceData, HpInfSpecialType type, AttackType attackType)
        {
            if(addhp == 0)
            {
                return;
            }

#if UNITY_EDITOR && TEST100
            //100场战斗输出
            if (addhp > 0)
            {
                if (exportOnceData.source != null)
                {
                    exportOnceData.source.exportTreatHp += addhp;
                }
            }
            else
            {
                if (exportOnceData.source != null)
                {
                    exportOnceData.source.exportDamHp += addhp;
                }
            }
#endif

            bool export = true;
            double exportHp = 0;
            if (this.state == FActorState.DEAD)
            {//已死亡，正常不应该走到这个接口里
                export = false;
                Debug.LogError("--------add hp error:AddHp to the hero who is die:" + this.heroId);
            }
            else if(this.state == FActorState.WAEKDEAD)
            {//假死状态，血量不做实际增减
                exportHp = addhp;
            }
            else if (this.stateManager.IsDieAfterLastAttack)
            {//己方回合结束后必死状态，血量不做实际增减
                exportHp = addhp;
            }
            else
            {
                if (addhp > 0)
                {//加血
                    //如果有加血减免百分比，则要处理减免
                    exportHp = addhp*(1+this.attribute.minusAddperhp);
                    if (exportHp < 1)
                        exportHp = 1;
                    if (this.stateManager.IsForbidAddHp)
                    {
                        exportHp = 0;
                        type = HpInfSpecialType.Immune;
                    }
                    else
                    {
                        this.attribute.hp += exportHp;
                        if (this.attribute.hp > this.attribute.maxHp)
                        {
                            this.attribute.hp = this.attribute.maxHp;
                        }
                        doHpChangeInRound(exportHp);
                    }
                }
                else {
                    addhp = addhp * this.player.engineData.getPlayerByCampType(this.player.enemyCamp).damageFactor; //乘以对面的减血系数
                    if (attackType == AttackType.PHY && (this.attribute.pshield > 0 || this.attribute.shield > 0))
                    {//物理减血且当前有物理血盾或者血盾
                        if((this.attribute.pshield + this.attribute.shield + addhp) >= 0)
                        {//血盾足够抵消
                            if((this.attribute.pshield + addhp) >= 0)
                            {//物理血盾足够抵消
                                this.attribute.pshield += addhp;
                                if(this.attribute.pshield <= 0)
                                {//如果物理血盾被减为0了，清除物理血盾Buff
                                    this.attribute.pshield = 0;
                                    buffManager.removePShieldBuff();
                                }
                            }
                            else
                            {//物理血盾不足以减，再减血盾
                                this.attribute.shield += (this.attribute.pshield + addhp);
                                if(this.attribute.pshield > 0)
                                {//如果有物理血盾，清除物理血盾Buff
                                    this.attribute.pshield = 0;
                                    buffManager.removePShieldBuff();
                                }
                                if (this.attribute.shield <= 0)
                                {//如果血盾被减为0了，清除血盾Buff
                                    this.attribute.shield = 0;
                                    buffManager.removeShieldBuff();
                                }
                            }
                            exportHp = 0;
                            type = HpInfSpecialType.Shield;
                        }
                        else
                        {//血盾不足以抵消
                            exportHp = this.attribute.pshield + this.attribute.shield + addhp;
                            if (this.attribute.pshield > 0)
                            {//清除物理血盾Buff
                                this.attribute.pshield = 0;
                                buffManager.removePShieldBuff();
                            }
                            if (this.attribute.shield > 0)
                            {//清除血盾Buff
                                this.attribute.shield = 0;
                                buffManager.removeShieldBuff();
                            }
                            //减血
                            exportHp = MinusHP(exportHp, exportOnceData);
                        }
                    }
                    else if(attackType == AttackType.MAG && (this.attribute.mshield > 0 || this.attribute.shield > 0))
                    {//魔法减血且当前有魔法血盾或者血盾
                        if ((this.attribute.mshield + this.attribute.shield + addhp) >= 0)
                        {//血盾足够抵消
                            if ((this.attribute.mshield + addhp) >= 0)
                            {//魔法血盾足够抵消
                                this.attribute.mshield += addhp;
                                if (this.attribute.mshield <= 0)
                                {//如果魔法血盾被减为0了，清除魔法血盾Buff
                                    this.attribute.mshield = 0;
                                    buffManager.removeMShieldBuff();
                                }
                            }
                            else
                            {//魔法血盾不足以减，再减血盾
                                this.attribute.shield += (this.attribute.mshield + addhp);
                                if (this.attribute.mshield > 0)
                                {//如果有魔法血盾，清除魔法血盾Buff
                                    this.attribute.mshield = 0;
                                    buffManager.removeMShieldBuff();
                                }
                                if (this.attribute.shield <= 0)
                                {//如果血盾被减为0了，清除血盾Buff
                                    this.attribute.shield = 0;
                                    buffManager.removeShieldBuff();
                                }
                            }
                            exportHp = 0;
                            type = HpInfSpecialType.Shield;
                        }
                        else
                        {//血盾不足以抵消
                            exportHp = this.attribute.mshield + this.attribute.shield + addhp;
                            if (this.attribute.mshield > 0)
                            {//清除魔法血盾Buff
                                this.attribute.mshield = 0;
                                buffManager.removeMShieldBuff();
                            }
                            if (this.attribute.shield > 0)
                            {//清除血盾Buff
                                this.attribute.shield = 0;
                                buffManager.removeShieldBuff();
                            }
                            //减血
                            exportHp = MinusHP(exportHp, exportOnceData);
                        }
                    }
                    else
                    {
                        //减血
                        exportHp = addhp;
                        exportHp = MinusHP(exportHp, exportOnceData);
                    }
                }
            }
            //已经处于假死状态，且当前没有人以我为技能目标,且自身当前没有在释放技能，直接处理死亡
            if (this.state == FActorState.WAEKDEAD && this.player.engineData.GetNumActorAttack(this) == 0)
            {
                if ((this.doSkill != null && this.doSkill.isFirstCastStart) || (this.doUltimateSkill != null && this.doUltimateSkill.isFirstCastStart))
                {//当前人物已经有技能正在释放，需要等他当前的cast释放完毕后再处理死亡

                }
                else
                {
                    DoDead(this.player.engineData, exportOnceData);
                }
            }

            Debug.LogFightMsg("--------add hp: " + exportHp + " ==>curHp: " + this.attribute.hp + "   ==>heroId:" + this.heroId + ",uniqueId:" + this.uniqueId + "   ==>type:" + type);
            if (export)
            {
                FExportValue exportValue = new FExportValue();
                exportValue.Init(exportOnceData.source, this, ExportValueClass.HP, exportHp, 0, type);
                exportOnceData.values.Add(exportValue);
            }
        }

        public double MinusHP(double exportHp, FExportOnceData exportOnceData)
        {
            bool hpless0 = false;
            if (this.attribute.angerTohpAF > 0 && this.player.angerNum > 0)
            {//先用怒气抵消血量
                double af = this.player.angerNum / this.attribute.angerTohpAF;
                double canCounteractHp = Math.Floor(af) * this.attribute.angerTohpHF; //能够抵消的血量值
                if (canCounteractHp >= -exportHp)
                {//怒气足够抵消
                    double hf = -exportHp / this.attribute.angerTohpHF;
                    double exportAnger = Math.Ceiling(hf) * this.attribute.angerTohpAF;
                    this.player.AddAnger(-exportAnger, this, exportOnceData);
                    exportHp = 0;
                }
                else
                {//先减怒气，再减血量
                    double exportAnger = Math.Floor(af) * this.attribute.angerTohpAF;
                    this.player.AddAnger(-exportAnger, this, exportOnceData);
                    exportHp += canCounteractHp;
                    if(this.attribute.maxhpLimitDam < 0 && this.attribute.maxhpLimitDam > exportHp)
                    {
                        exportHp = this.attribute.maxhpLimitDam;
                    }
                    if (exportHp > -1)
                        exportHp = -1;
                    this.attribute.hp += exportHp;
                    if (this.attribute.hp <= 0)
                    {
                        hpless0 = true;
                    }
                    else
                    {
                        doHpChangeInRound(exportHp);
                    }
                }

            }
            else
            {
                if (this.attribute.maxhpLimitDam < 0 && this.attribute.maxhpLimitDam > exportHp)
                {
                    exportHp = this.attribute.maxhpLimitDam;
                }
                if (exportHp > -1)
                    exportHp = -1;
                this.attribute.hp += exportHp;
                if (this.attribute.hp <= 0)
                {
                    hpless0 = true;
                }
                else
                {
                    doHpChangeInRound(exportHp);
                }
            }
            if (hpless0)
            {
                //处理血量小于0时的buff
                this.buffProc.LoadBuffByTimer(TalentBuffTriggerTimer.HpLessZero);
                if (this.stateManager.IsDieAfterLastAttack)
                {
                    this.attribute.hp = 0.01;
                }
                else
                {
                    DoWeakDead(this.player.engineData);
                }
            }
            else
            {
                this.attribute.hpMinusVal += exportHp;
                if (this.attribute.perhpreduceToangerAF > 0 && this.attribute.hpMinusVal < this.attribute.perhpreduceToangerHF)
                {//降低血量增加怒气
                    double hf = this.attribute.hpMinusVal / this.attribute.perhpreduceToangerHF;
                    double exportAnger = Math.Floor(hf) * this.attribute.perhpreduceToangerAF;
                    this.attribute.hpMinusVal -= (Math.Floor(hf) * this.attribute.perhpreduceToangerHF);
                    this.player.AddAnger(exportAnger, this, exportOnceData);
                }
            }
            return exportHp;
        }
        public void doHpChangeInRound(double changeHp)
        {
            this.attribute.hpChangeInRound += changeHp;
            if (this.player.engineData.curRoundCamp == this.player.enemyCamp && (this.attribute.hpChangeInRound/this.attribute.maxHp) <= -0.4)
            {//当前处在被攻击回合，并且减血到达总血量的40%，触发己方其他人的回血buff
                foreach (var teamActor in this.player.actors)
                {
                    if (teamActor.state == FActorState.DEAD || teamActor.uniqueId.Equals(this.uniqueId))
                    {
                        continue;
                    }
                    else
                    {
                        teamActor.buffProc.LoadBuffToTargetByTimer(TalentBuffTriggerTimer.HpDown40InRound,this);
                    }
                }
            }

        }

        public double GetValueByType(string type)
        {
            double val = 0;
            switch(type)
            {
                case TableFactorConst.row:
                    val = this.MainPosition.row;
                    break;
                case TableFactorConst.col:
                    val = this.MainPosition.col;
                    break;
                case TableFactorConst.space:
                    val = this.space;
                    break;
                case TableFactorConst.selfComboNum:
                    val = this.selfComboNum;
                    break;
                case TableFactorConst.comboNum:
                    val = this.player.comboNum;
                    break;
                case TableFactorConst.totalLeftHp:
                    foreach (var a in this.player.actors)
                    {
                        if (a.state != FActorState.DEAD)
                        {
                            val += a.attribute.hp;
                        }
                    }
                    break;
                case TableFactorConst.totalMaxHp:
                    foreach (var a in this.player.actors)
                    {
                        val += a.attribute.maxHp;
                    }
                    break;
                case TableFactorConst.selfRoundNum:
                    val = (int)((this.player.engineData.roundNum + 1) / 2);
                    break;
                case TableFactorConst.skillClass://远程 or 近战
                    val = (double)this.curSkillClass;
                    break;
                case TableFactorConst.skillType://物理 or 魔法
                    val = (double)this.attackType;
                    break;
                case TableFactorConst.curSkillType:
                    if (this.doSkill != null)
                    {
                        val = (double)this.doSkill.attackType;
                    }
                    else if(this.doUltimateSkill != null)
                    {
                        val = (double)this.doUltimateSkill.attackType;
                    }
                    else
                    {
                        val = (double)this.attackType;
                    }
                    break;
                case TableFactorConst.curSkillIndex:
                    if (this.doSkill != null)
                    {
                        val = (double)this.doSkill.index;
                    }
                    else if (this.doUltimateSkill != null)
                    {
                        val = (double)this.doUltimateSkill.index;
                    }
                    else
                    {
                        val = -1;
                    }
                    break;
                case TableFactorConst.teammateDeadNum:
                    foreach(var a in this.player.actors)
                    {
                        if(a.state == FActorState.DEAD)
                        {
                            val++;
                        }
                    }
                    break;
                case TableFactorConst.aliveNum:
                    foreach (var a in this.player.actors)
                    {
                        if (a.state != FActorState.DEAD)
                        {
                            val++;
                        }
                    }
                    break;
                case TableFactorConst.aliveEnemyNum:
                    foreach (var a in this.player.engineData.getPlayerByCampType(this.player.enemyCamp).actors)
                    {
                        if (a.state != FActorState.DEAD)
                        {
                            val++;
                        }
                    }
                    break;
                case TableFactorConst.doskillNum:
                    val = this.player.GetSkillingActorNum();
                    break;
                case TableFactorConst.targetOfEnemyNum:
                    val = this.player.engineData.GetNumActorAttack(this);
                    break;
                case TableFactorConst.speState:
                    val = (double)this.speState;
                    break;
                case TableFactorConst.roundMinusAngerNum:
                    val = this.player.costAngerInRound;
                    break;
                case TableFactorConst.debuffNum:
                    val = this.buffManager.GetDebuffNum();
                    break;
                case TableFactorConst.hp:
                    val = this.attribute.hp;
                    break;
                case TableFactorConst.maxHp:
                    val = this.attribute.maxHp;
                    break;
                case TableFactorConst.att:
                    val = this.attribute.att.value;
                    break;
                case TableFactorConst.patt:
                    val = this.attribute.patt.value;
                    break;
                case TableFactorConst.matt:
                    val = this.attribute.matt.value;
                    break;
                case TableFactorConst.pdef:
                    val = this.attribute.pdef.value;
                    break;
                case TableFactorConst.mdef:
                    val = this.attribute.mdef.value;
                    break;
                case TableFactorConst.hit:
                    val = this.attribute.hit;
                    break;
                case TableFactorConst.dodge:
                    val = this.attribute.dodge;
                    break;
                case TableFactorConst.cri:
                    val = this.attribute.cri;
                    break;
                case TableFactorConst.antiCri:
                    val = this.attribute.antiCri;
                    break;
                case TableFactorConst.criFactor:
                    val = this.attribute.criFactor;
                    break;
                case TableFactorConst.cure:
                    val = this.attribute.cure;
                    break;
                case TableFactorConst.heal:
                    val = this.attribute.heal;
                    break;
                case TableFactorConst.treatAdd:
                    val = this.attribute.treatAdd;
                    break;
                case TableFactorConst.damageAdd:
                    val = this.attribute.damageAdd;
                    break;
                case TableFactorConst.damageReduce:
                    val = this.attribute.damageReduce;
                    break;
                case TableFactorConst.pdamageReduce:
                    val = this.attribute.pdamageReduce;
                    break;
                case TableFactorConst.mdamageReduce:
                    val = this.attribute.mdamageReduce;
                    break;
                case TableFactorConst.bleeding:
                    val = this.attribute.bleeding;
                    break;
                case TableFactorConst.anger:
                    val = this.player.angerNum;
                    break;
                case TableFactorConst.shield:
                    val = this.attribute.shield+ this.attribute.pshield+ this.attribute.mshield;
                    break;
                case TableFactorConst.invisible:
                    val = this.stateManager.invisibleNumber;
                    break;
                case TableFactorConst.invincible:
                    val = this.stateManager.invincibleNumber;
                    break;
                case TableFactorConst.mustHit:
                    val = this.stateManager.mustHitNumber;
                    break;
                case TableFactorConst.mustCri:
                    val = this.stateManager.mustCriNumber;
                    break;
                case TableFactorConst.dizzy:
                    val = this.stateManager.dizzyNumber;
                    break;
                case TableFactorConst.fireDam:
                    val = this.stateManager.fireNumber;
                    break;
                case TableFactorConst.poisonDam:
                    val = this.stateManager.poisonNumber;
                    break;
                case TableFactorConst.ice:
                    val = this.stateManager.iceNumber;
                    break;
                case TableFactorConst.forbidFirstSkill:
                    val = this.stateManager.forbidFirstSkillNumber;
                    break;
                case TableFactorConst.forbidSecondSkill:
                    val = this.stateManager.forbidSecondSkillNumber;
                    break;
                case TableFactorConst.forbidUltimateSkill:
                    val = this.stateManager.forbidUltimateSkillNumber;
                    break;
                case TableFactorConst.forbidAddSkillAnger:
                    val = this.stateManager.forbidAddSkillAngerNumber;
                    break;
                case TableFactorConst.forbidAddHp:
                    val = this.stateManager.forbidAddHpNumber;
                    break;
                case TableFactorConst.immuneDef:
                    val = this.stateManager.immuneDefNumber;
                    break;
                case TableFactorConst.immuneDizzy:
                    val = this.stateManager.immuneDizzyNumber;
                    break;
                case TableFactorConst.immuneDebuff:
                    val = this.stateManager.immuneDebuffNumber;
                    break;
                case TableFactorConst.immuneFloatBreak:
                    val = this.stateManager.immuneFloatBreakNumber;
                    break;
                case TableFactorConst.canNotKill:
                    val = this.stateManager.canNotKillNumber;
                    break;
                default:
                    //未处理的选择范围类型
                    Debug.LogError("FActor getValueByType--->Unknown type:" + type);
                    break;

            }
            return val;
        }

        public bool IsDetectionPosition(FPosition p)
        {
            foreach (var standPos in positions)
            {
                if (standPos == p)
                    return true;
            }
            return false;
        }
        public bool IsDetectionPosition(int fpid)
        {
            foreach (var standPos in positions)
            {
                if (standPos.ToFPID() == fpid)
                    return true;
            }
            return false;
        }
        public bool IsDetectionInRow(int row)
        {
            foreach (var standPos in positions)
            {
                if (standPos.row == row)
                    return true;
            }
            return false;
        }

        public bool IsDetectionInCol(int col)
        {
            foreach (var standPos in positions)
            {
                if (standPos.col == col)
                    return true;
            }
            return false;
        }

        public double getFloatTimeBySkill(SpeState causeSpeState)
        {
            double time = 0;
            if (this.stateManager.IsImmuneFloatBreak || this.attribute.shield > 0)
            {
                time = 0;
                return time;
            }
            bool b1 = (causeSpeState == SpeState.FLOAT || (this.speState == SpeState.FLOAT && causeSpeState != SpeState.FALL));
            bool b2 = this.defaultSpeState != SpeState.FLOAT && this.speState != SpeState.FALL;
            bool b3 = !this.unableStates.Contains(SpeState.FLOAT);
            bool result = b1 && b2 && b3;
            if (result)
            {
                time = this.player.engineData.tableDataUtil.GetFloatDuration();
                this.speState = SpeState.FLOAT;
                this.fallTime = 0;
                this.floatTime = time;
                this.floatStartTime = this.player.engineData.roundTime;
            }
            else
            {
                time = 0;
            }
            return time;
        }

        public double getFallTimeBySkill(SpeState causeSpeState)
        {
            double time = 0;
            if (this.stateManager.IsImmuneFloatBreak || this.attribute.shield > 0)
            {
                time = 0;
                return time;
            }
            bool b1 = (causeSpeState == SpeState.FALL && this.speState != SpeState.FALL); //倒地不能被重置
            bool b2 = this.defaultSpeState != SpeState.FALL;
            bool b3 = !this.unableStates.Contains(SpeState.FALL);
            bool res = b1 && b2 && b3;
            if (res)
            {
                time = this.player.engineData.tableDataUtil.GetBreakDuration();
                this.speState = SpeState.FALL;
                this.floatTime = 0;
                this.fallTime = time;
                this.fallStartTime = this.player.engineData.roundTime;
            }
            else
            {
                time = 0;
            }
            return time;
        }
        //index 技能的序号
        //@return 是否是有效操作
        public bool DoSkill(int index, EngineData data)
        {
            if (this.state == FActorState.WAEKDEAD || this.state == FActorState.DEAD)
                return false;

            //如果当前正在或者准备释放大招,不能再释放其他招式
            if (data.ultimateSkill != null)
            {
                return false;
            }

            //mxd 这里还要验证合法性,技能是否是放过等
            FSkill skill = null;
            foreach (var obj in this.skills)
            {
                if (obj.index == index)
                {
                    skill = obj;
                    break;
                }
            }
            if (skill == null)
                return false;

            //如果当前已经准备释放大招,并且这次使用的技能也是大招,取消
            if (data.ultimateSkill != null && skill.IsUltimate == true)
            {
                return false;
            }
            
            //技能是否可以释放(比如buff)
            if (isCanDoSkill(skill) == false)
            {
                return false;
            }

            //如果是大招,标记进入准备释放大招的状态
            if (skill.IsUltimate == true)
            {
                skill.Wait(data);
                data.ultimateSkill = skill;
            }
            else
            {
                //如果当前这个人没有正在释放的技能,立刻释放, 有正在释放的技能,加入到等待队列
                if (doSkill == null)
                {
                    SkillBegin(skill, data);
                }
                else
                {
                    skill.Wait(data);
                    waitSkills.Add(skill);
                }
            }

            //mxd 通知释放技能成功,在技能添加进序列以后再通知，避免出现时间差
            if (data.callback != null)
                data.callback.SkillPress(this.player.camp, this.uniqueId, index);
            return true;
        }

        //
        public void Update(EngineData data)
        {
            //处理浮空倒地更新
            if(this.floatTime > 0)
            {
                if((data.roundTime - this.floatStartTime) >= this.floatTime)
                {//浮空时间到，回到默认状态
                    this.speState = this.defaultSpeState;
                    this.floatTime = 0;
                    this.fallTime = 0;
                }
            }
            if (this.fallTime > 0)
            {
                if ((data.roundTime - this.fallStartTime) >= this.fallTime)
                {//浮空时间到，回到默认状态
                    this.speState = this.defaultSpeState;
                    this.floatTime = 0;
                    this.fallTime = 0;
                }
            }
            //处理人物状态
            switch (this.state)
            {
                case FActorState.IDLE:
                    {

                    }
                    break;
                case FActorState.SKILL:
                    {

                    }
                    break;
                case FActorState.WAIT:
                    {
                        //如果等待时间超过了直接回原位
                        if(data.roundTime >= this.waitTime)
                        {
                            DoIdle(data);
                        }
                    }
                    break;
                case FActorState.WAEKDEAD:
                    {

                    }
                    break;
                case FActorState.DEAD:
                    {

                    }
                    break;
            }

            //更新时间相关的buff状态
            this.buffManager.Update(data);

            //技能
            //如果当前自己没有大招
            if (this.doUltimateSkill == null)
            {
                //如果全局有需要放的大招
                if (data.ultimateSkill != null)
                {
                    //如果这个全局大招是自己
                    if (data.ultimateSkill.actor == this)
                    {
                        //如果当前没有人再释放普通技能,开始释放大招
                        if (data.HasAnySkilling() == false)
                        {
                            SkillBegin(data.ultimateSkill, data);
                        }
                    }
                }

                //?这里要放 大招update前面？ 避免放完大招立刻放普通技能
                //如果大招已经再等待或者释放, 不能执行队列的技能
                if (data.ultimateSkill == null && doSkill == null)
                {
                    if (waitSkills.Count > 0)
                    {
                        FSkill skill = waitSkills[0];
                        waitSkills.RemoveAt(0);
                        SkillBegin(skill, data);
                    }
                }
                if (doSkill != null)
                {
                    doSkill.Update(data);
                }
            }
            else
            {
                this.doUltimateSkill.Update(data);
            }
        }

        public void ResetRound(EngineData data)
        {
            if(this.state != FActorState.DEAD && this.state != FActorState.WAEKDEAD)
                this.state = FActorState.IDLE;

            doSkill = null;
            waitSkills.Clear();
            doUltimateSkill = null;
            this.attribute.hpMinusVal = 0;
            this.attribute.hpChangeInRound = 0;
            this.selfComboNum = 0;

            foreach (var skill in this.skills)
            {
                skill.ResetRound(data);
            }

            this.speState = (SpeState)this.heroData.DefaultState;
            this.floatStartTime = data.roundTime;
            this.floatTime = 0;
            this.fallStartTime = data.roundTime;
            this.fallTime = 0;
            ResetPosition();
            this.curCastSelectPointRule = -1;
            this.waitTime = 0;
        }

        public void ResetPosition()
        {
            this.position = this.positions[0];
            this.curCastTargetPosition = null;
            this.curCastSelectPointRule = -1;
        }

        //真正开始释放一个技能
        public void SkillBegin(FSkill skill, EngineData data)
        {
            //mxd ? 校验一下技能是不是自己的

            skill.Do(data);
            //如果没有打到敌人
            if (skill.target == null)
                return;

            this.state = FActorState.SKILL;
            if (skill.IsUltimate == true)
            {
                this.doUltimateSkill = skill;
            }
            else
            {
                this.doSkill = skill;
            }
            this.behitActors.Clear();
        }

        public void SkillEnd(EngineData data)
        {
            //如果当前释放的是大招,设置全局大招的null
            if (this.doUltimateSkill == data.ultimateSkill)
                data.ultimateSkill = null;

            //如果技能结束了,doSkill设置null,等下一次循环waitSkills再添加
            if (this.doSkill != null)
                this.doSkill.state = FSkillState.FINISH;
            if (this.doUltimateSkill != null)
                this.doUltimateSkill.state = FSkillState.FINISH;
            this.doSkill = null;
            this.doUltimateSkill = null;

            if (this.state != FActorState.DEAD && this.state != FActorState.WAEKDEAD)
            {
                bool needWait = false;
                foreach (var skill in skills) {
                    if (skill.IsUltimate)
                        continue;
                    if (isCanDoSkill(skill)) {
                        needWait = true;
                        break;
                    }
                }
                if (waitSkills.Count > 0)
                {
                    needWait = true;
                }
                if (needWait)
                {
                    //是否进入攻击等待状态
                    DoWait(data);
                }
                else {
                    DoIdle(data);
                }
            }
        }

        //回原地
        public void DoIdle(EngineData data)
        {
            if(this.state != FActorState.DEAD && this.state != FActorState.WAEKDEAD)
                this.state = FActorState.IDLE;
            ResetPosition();
        }

        //不退回原地,进入等待下次攻击的状态
        public void DoWait(EngineData data)
        {
            //如果就在原地不需要返回
            if (this.position == this.positions[0])
            {
                this.state = FActorState.IDLE;
                return;
            }
            
            this.state = FActorState.WAIT;
            this.waitTime = data.roundTime + data.tableDataUtil.GetContinueAttackWaitTimeout();
        }

        //进入假死状态
        public void DoWeakDead(EngineData data)
        {
            this.attribute.hp = 0;
            this.state = FActorState.WAEKDEAD;
        }

        //进入死亡状态
        public void DoDead(EngineData data, FExportOnceData exportOnceData)
        {
            this.waitSkills.Clear();
            if (this.doSkill != null || this.doUltimateSkill != null)
            {
                this.SkillEnd(data);
            }
            foreach (var skill in this.skills)
            {
                skill.state = FSkillState.FINISH;
            }
            
            this.attribute.hp = 0;
            this.state = FActorState.DEAD;
            this.buffManager.ClearAllBuff();
            ProcDeadTalent(data);
            if(this.state == FActorState.DEAD)
            {
                Debug.LogFightMsg100("--------dead: round=" + data.roundNum + ", DoDead:" + this.heroId + ", camp:"+this.player.camp+", position:" + this.MainPosition.ToFPID());
                Debug.LogFightMsg("--------dead: time=" + data.roundTime + ", DoDead:" + this.heroId + ",uniqueId:" + this.uniqueId);
                data.compute.ActorDead(this);
                this.player.deadActors.Add(this);//当场战斗死亡的人数加1
                //输出
                exportOnceData.deadActors.Add(this);
            }
        }

        public void ProcDeadTalent(EngineData data)
        {
            //处理死亡时的buff
            this.buffProc.LoadBuffByTimer(TalentBuffTriggerTimer.Die);
            //处理队友死亡时的buff
            foreach (var teamActor in this.player.actors)
            {
                if (teamActor.state == FActorState.DEAD)
                {
                    continue;
                }
                else
                {
                    teamActor.buffProc.LoadBuffByTimer(TalentBuffTriggerTimer.TeammateDie);
                }
            }
        }

        public FSkill GetFSkill(int index) {
            foreach (var skill in skills) {
                if (skill.index == index)
                    return skill;
            }
            return null;
        }

        public FSkill GetFSkill(string skillId) {
            foreach (var skill in skills) {
                if (skill.id == skillId)
                    return skill;
            }
            return null;
        }

        //用于回合开始前判断技能是否CD或者被禁止
        public bool isSkillReady(FSkill skill)
        {
            if (skill.state != FSkillState.None || this.state == FActorState.WAEKDEAD || this.state == FActorState.DEAD)
            {
                return false;
            }
            if (this.stateManager.IsDizzy)
            {
                return false;
            }
            if (skill.cooldownCur > 0)
            {//被冷却中
                return false;
            }
            if (skill.IsUltimate
                    && skill.actor.stateManager.IsForbidUltimateSkill) //被禁止
            {
                return false;
            }
            else if (skill.index == 0
                && skill.actor.stateManager.isForbidFirstSkill) //被禁止
            {
                return false;
            }
            else if (skill.index == 1
               && skill.actor.stateManager.IsForbidSecondSkill) //被禁止
            {
                return false;
            }

            return true;
        }

        //判断技能是否可以释放的接口
        public bool isCanDoSkill(FSkill skill)
        {
            if (skill.state != FSkillState.None || this.state == FActorState.WAEKDEAD || this.state== FActorState.DEAD)
            {
                return false;
            }
            if (this.stateManager.IsDizzy)
            {
                return false;
            }
            if (skill.cooldownCur > 0)
            {//被冷却中
                return false;
            }
            if (skill.IsUltimate && skill.actor.player.angerNum < this.ultimateCostAnger)
            {//大招需要满足100点怒气值
                return false;
            }
            if (skill.IsUltimate
                    && skill.actor.stateManager.IsForbidUltimateSkill) //被禁止
            {
                return false;
            }
            else if (skill.index == 0
                && skill.actor.stateManager.isForbidFirstSkill) //被禁止
            {
                return false;
            }
            else if (skill.index == 1
               && skill.actor.stateManager.IsForbidSecondSkill) //被禁止
            {
                return false;
            }

            return true;
        }

        //判断技能是否处于激活状态（Wait or Doing or LAST）
        public bool isActive(FSkill skill)
        {
            if (skill.enable == false)
                return false;
            if (skill.state == FSkillState.None)
                return false;
            if (skill.state == FSkillState.FINISH)
                return false;
            return true;
        }

        //设置技能开关
        public void SetSkill(int skillIndex, bool enable)
        {
            FSkill skill = GetFSkill(skillIndex);
            if (skill != null)
            {
                skill.enable = enable;
            }
        }
    }
}
  